<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="HYLih" id="HYLih"><span data-lake-id="u1977b5ea" id="u1977b5ea">典型回答</span></h1>
  <p data-lake-id="u392ba416" id="u392ba416"><br></p>
  <p data-lake-id="u7d145ffe" id="u7d145ffe"><span data-lake-id="u260bc025" id="u260bc025">在我们做了分库分表之后，数据会散落在不同的数据库中，这时候跨多个库的分页查询、以及排序等都非常的麻烦。</span></p>
  <p data-lake-id="uc023f632" id="uc023f632"><span data-lake-id="u2d1400e3" id="u2d1400e3">​</span><br></p>
  <p data-lake-id="uefeb563e" id="uefeb563e"><span data-lake-id="u30aa0d14" id="u30aa0d14">如果分的库不多，那么我们还可以通过扫表的方式把多个库中的数据都取出来，然后在内存中进行分页和排序。</span></p>
  <p data-lake-id="u4cb1cc72" id="u4cb1cc72"><span data-lake-id="u903fda27" id="u903fda27">​</span><br></p>
  <p data-lake-id="u001de41b" id="u001de41b"><span data-lake-id="u31224a28" id="u31224a28">比如我要查询limit 100,100 的话，有三个库，那我就分别到这三个库中把0 - 200之间的数据都取回来，然后再在内存中给他们排序，之后，再取出第100-200之间的数据。</span></p>
  <p data-lake-id="u879724d5" id="u879724d5"><span data-lake-id="u10bf2793" id="u10bf2793">​</span><br></p>
  <p data-lake-id="u19ef148d" id="u19ef148d"><span data-lake-id="u22d89950" id="u22d89950">这种做法非常的麻烦，而且随着偏移量越大，当要分的页很多的时候，可想而知这种方法根本就不靠谱。</span></p>
  <p data-lake-id="u5a97d5cd" id="u5a97d5cd"><span data-lake-id="uaacdc04c" id="uaacdc04c">​</span><br></p>
  <p data-lake-id="u23e26034" id="u23e26034"><span data-lake-id="u0b5fb0c2" id="u0b5fb0c2">网上有很多文章写了几种做法，还起了几个名字，比如</span><span data-lake-id="uad680e3e" id="uad680e3e" style="color: rgb(18, 18, 18)">全局视野法、二次查询法、业务折衷法的，在我看来，这几种做法根本就都不靠谱，而且只会带来复杂的理解和维护成本，而且没有办法都一定的前提条件限制。</span></p>
  <p data-lake-id="ueb604a50" id="ueb604a50"><span data-lake-id="ue0c81da8" id="ue0c81da8" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="u2618578b" id="u2618578b"><strong><span data-lake-id="ud3d34d35" id="ud3d34d35" style="color: rgb(18, 18, 18)">一般来说，在企业中是怎么做的呢？</span></strong><span data-lake-id="u808f374b" id="u808f374b" style="color: rgb(18, 18, 18)">我们还是拿订单的分库分表举例，当我们用买家ID分表之后：</span></p>
  <p data-lake-id="ua0117f75" id="ua0117f75"><span data-lake-id="ub858bf73" id="ub858bf73" style="color: rgb(18, 18, 18)">​</span><br></p>
  <h3 data-lake-id="qNHMi" id="qNHMi"><span data-lake-id="uaac4bec9" id="uaac4bec9" style="color: rgb(18, 18, 18)">shardingkey查询</span></h3>
  <p data-lake-id="u9ca45389" id="u9ca45389"><span data-lake-id="u6617ed9a" id="u6617ed9a" style="color: rgb(18, 18, 18)">一般来说，买家的订单查询是最高频的，而对于买家来说，查询的时候天然就是可以带买家ID的，所以就可以路由到单个库中进行分页以及排序了。</span></p>
  <p data-lake-id="u74d8a7d6" id="u74d8a7d6"><span data-lake-id="ub666ac5f" id="ub666ac5f" style="color: rgb(18, 18, 18)">​</span><br></p>
  <h3 data-lake-id="qvQFg" id="qvQFg"><span data-lake-id="u9d6533d8" id="u9d6533d8" style="color: rgb(18, 18, 18)">非shardingkey的关键查询</span></h3>
  <p data-lake-id="u2a1c4bb4" id="u2a1c4bb4"><span data-lake-id="u50940882" id="u50940882" style="color: rgb(18, 18, 18)">那么，电商网站上不仅有买家，还有卖家，他们的查询也很高频，该怎么做呢？</span></p>
  <p data-lake-id="ud0331f38" id="ud0331f38"><span data-lake-id="u596bb940" id="u596bb940" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="ucfb597a5" id="ucfb597a5"><span data-lake-id="ueaa549af" id="ueaa549af" style="color: rgb(18, 18, 18)">一般来说，业务上都会采用空间换时间的方案，同步出一张按照卖家维度做分表的表来，同步的过程中一般是使用canal基于bin log 做自动同步。虽然这种情况下可能存在秒级的延迟，但是一般业务上来说都是可以接受的。</span></p>
  <p data-lake-id="uf1936c29" id="uf1936c29"><span data-lake-id="u5d29e025" id="u5d29e025" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="u427a1057" id="u427a1057"><span data-lake-id="uf0ded2ef" id="uf0ded2ef" style="color: rgb(18, 18, 18)">也就是说，当一条订单创建出来之后，会在买家表创建一条记录，以买家ID作为分表字段，同时，也会在卖家表创建一条记录出来，用卖家ID进行分表。</span></p>
  <p data-lake-id="uaf737aef" id="uaf737aef"><span data-lake-id="u542f1c54" id="u542f1c54" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="ud52f060f" id="ud52f060f"><span data-lake-id="u1802e0f2" id="u1802e0f2" style="color: rgb(18, 18, 18)">并且这张卖家表不会做任何写操作，只提供查询服务，完全可以用一些机器配置没有那么高的数据库实例。</span></p>
  <p data-lake-id="u07b2ccd9" id="u07b2ccd9"><span data-lake-id="u932be121" id="u932be121" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="u0cfc343c" id="u0cfc343c"><span data-lake-id="u51e0833d" id="u51e0833d" style="color: rgb(18, 18, 18)">这样，卖家的分页等查询就可以直连卖家表做查询了。</span></p>
  <p data-lake-id="u1346477c" id="u1346477c"><span data-lake-id="u3885fe80" id="u3885fe80" style="color: rgb(18, 18, 18)">​</span><br></p>
  <h3 data-lake-id="NCSC8" id="NCSC8"><span data-lake-id="u89f1d429" id="u89f1d429" style="color: rgb(18, 18, 18)">非shardingkey的复杂查询</span></h3>
  <p data-lake-id="u69f6cdd6" id="u69f6cdd6"><span data-lake-id="u45a84458" id="u45a84458" style="color: rgb(18, 18, 18)">那除了买家、卖家以外，其他的查询怎么办呢？</span></p>
  <p data-lake-id="ue6578410" id="ue6578410"><span data-lake-id="ua1f352cf" id="ua1f352cf" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="ue70e600d" id="ue70e600d"><span data-lake-id="u9db0c306" id="u9db0c306" style="color: rgb(18, 18, 18)">一般来说，</span><strong><span data-lake-id="u3b81e3f4" id="u3b81e3f4" style="color: rgb(18, 18, 18)">大型互联网公司用的比较多的方案就是使用分布式数据仓库来实现</span></strong><span data-lake-id="u0fe687e0" id="u0fe687e0" style="color: rgb(18, 18, 18)">，也就是说我们会把这些数据同步到像TiDB、PolarDB、AnalyticDB等这些数据库中，或者同步到ES中，然后在这些数据库中做数据的聚合查询。</span></p>
  <p data-lake-id="u0467e967" id="u0467e967"><span data-lake-id="u1f3a87ac" id="u1f3a87ac" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="u03380794" id="u03380794"><span data-lake-id="u81879c10" id="u81879c10" style="color: rgb(18, 18, 18)">有人说，都用了MySQL了，还要用这些数据库，那方案也太重了，搞的这么复杂干什么？</span></p>
  <p data-lake-id="u256e3a69" id="u256e3a69"><span data-lake-id="ud4a099bc" id="ud4a099bc" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="u05a0bbee" id="u05a0bbee"><span data-lake-id="u75619c7d" id="u75619c7d" style="color: rgb(18, 18, 18)">那话又说回来了，分库分表，真不建议小公司、小团队用，这玩意本身就是意味着成本高的，又想要简单，又想要高效，又想要没问题？在技术领域，是没有银弹的。</span></p>
 </body>
</html>